perm filename A07.TEX[106,RWF] blob sn#827992 filedate 1986-11-10 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	\magnification\magstephalf
C00056 ENDMK
C⊗;
\magnification\magstephalf
\input macro.tex
\def\today{\ifcase\month\or
  January\or February\or March\or April\or May\or June\or
  July\or August\or September\or October\or November\or December\fi
  \space\number\day, \number\year}
\baselineskip 14pt
\rm
\line{\sevenrm a07.tex[106,phy] \today\hfill}

\font\rmn=cmr9

\bigskip
\line{{\bf Files.} (Assumes Strings) [RWF: needs rewriting]\hfil}

A file is  a sequence  of characters  or data.   Because it  is 
typically stored  in
magnetic disc memory, it is permanent and there is room for it to be  very
long, but (unlike  an array) it  can only be  created or used  in a  fixed
left-to-right order.  A file may be read or written by a program.  At  any
given moment, a~file can be  in one of  three conditions (called  modes):
closed, open  for  reading,  open  for writing.   There  is  a  family  of
operations, called input operations, that can only be done on a file that
is open for reading.  The input operations bring information from the file
into the program.  There  is another family  of operations, called  output
operations, which can only  be done on  a file that  is open for  writing.
Opening a file for writing
is a  bit like checking a book  out of the library;  nobody
else can use the file while you  have it open, and  it must eventually  be
closed again.

A file in Pascal has  two names; an internal name,  by which it is  called
inside the Pascal program, and an external name, by which it is stored  in
the  computer's  directory,  and  which is
used  in  editing  and  other  executive operations.
Usually, a  Pascal implementation  allows  the user to specify an external  name
for each internal name; this allows a single Pascal program  to
be applied to  many different  files.  The relation  between internal  and
external names is closely analogous to the relation between parameters and
arguments.

In the  definitions and  examples  that follow,  we  shall use  {\tt IN} as
exemplifying the  internal  name of  a  file  which has  been  opened  for
reading, {\tt OUT} as the internal name of  a file which has been opened  for
writing, and {\tt ANY} as a typical internal name of a file in any mode.  We
shall use {\tt INX}, {\tt OUTX}, 
and {\tt ANYX} in the same way as the  corresponding
external names.  We shall use {\tt I}, {\tt R},
{\tt C}, and~{\tt B} as typical variables of types
{\tt INTEGER}, {\tt REAL}, {\tt CHAR}, and {\tt BOOLEAN}.

If a certain file is a sequence of components $e↓1 e↓2 e↓3\ldots e↓n$, and is open
for reading, there is  always a mark, akin  to a bookmark, separating  the
part of the file that  has already been read from  the part that has  not.
In our examples, we use @ as the read mark and 
to show that the file is open for reading.  When the file
is first opened for reading, it looks like $@e↓1 e↓2 e↓3\ldots e↓n$. When
all the components of the file have  been read, the file looks like 
$e↓1  e↓2 e↓3\ldots e↓n@$, which is
the end-of-file  condition for that  file.
If a file is  open
for writing, we show  this by including a  similar write mark,~\#.   All
writing is done at the right end of  the file, so a file open for  writing
initially looks like just~\#, and later looks like $e↓1 e↓2 e↓3\ldots e↓n\#$.

The files {\tt INPUT} and {\tt OUTPUT}, if used, are automatically opened
for reading and writing respectively. Their use may be [?] limited to those
modes.

The components of a file may be of any one type, except that files may not
be parts of other files. Common are files of integers, real numbers, and
Boolean values. Most common of all, though, are the files used to
represent text laid out in lines on pages, called text files. Many of
Pascal's operations are defined exclusively for text files. The files
{\tt INPUT} and {\tt OUTPUT} are automatically text files.

The components of a text file are a mixture of characters with other
symbols, principally an end-of-line symbol. [Check standard.]
The Pascal Standard also
allows an implementation to have a way to represent the end of a page
in a text file, but does not specify details. The end-of-line symbol,
which we shall call $\eol$, divides the characters of the text file into
lines, which in practice must be short enough for printing and viewing.
A~completed text file must end with an $\eol$, which Pascal automatically
provides under some conditions.

If a text file {\tt OUT} is in write mode, the statement
{\tt WRITE(OUT,X)}, where {\tt X} is a {\tt REAL}, {\tt INTEGER},
{\tt BOOLEAN}, or string expression, expresses
{\tt X} as a string of characters and appends it to the file at the end.
(For format details, see \_\_\_ .) The statement {\tt WRITELN(OUT)}
appends $\eol$ to the file. Useful built-in abbreviations are
{\tt WRITE(OUT,X$↓1$,...,X$↓n$)} for

{\obeylines\obeyspaces\let =\ \tt
        BEGIN WRITE(OUT,X$↓1$); $\ldots$ WRITE(OUT,X$↓n$); END
}

\noindent
and {\tt WRITELN(OUT,X$↓1$,...,X$↓n$)} for

{\obeylines\obeyspaces\let =\ \tt
        BEGIN WRITE(OUT,X$↓1$); $\ldots$ WRITE(OUT,X$↓n$); WRITELN END
}

\noindent
If the file involved is {\tt OUTPUT}, the above operations can be abbreviated
to {\tt WRITE(X)}, {\tt WRITELN}, {\tt WRITE(X$↓1$,...,X$↓n$)}, and
{\tt WRITELN(X$↓1$,...,X$↓n$)}. That is, {\tt OUTPUT} is the default
file for writing. It is therefore convenient to use {\tt OUTPUT} as the
main file to which a program writes.

Output text files for printing should be  limited to the width of the  printer,
typically
132 characters;  that  is,  your program  should  execute {\tt WRITELN} before
writing more than 132 characters.   At most 60~lines  will typically
fit on a  page;
the command {\tt PAGE(OUT)} can be  used to start at  the beginning of a  new
page, even if the old one is not  full.  (If {\tt PAGE} is not used, a new  page
will be started whenever a page fills up.)  [Check standard.]
Similarly, output to be viewed on
a typical terminal screen
should be at most 80~characters wide and (if you want it all to be visible
at once) 24~lines high.

If a text file {\tt IN} is in {\tt READ} mode, the statement {\tt READ(IN,X)}
takes from the file a value of {\tt REAL}, {\tt INTEGER}, or {\tt CHAR} type
and assigns it to the variable~{\tt X}, which must be suitable. If {\tt X}~is
of a numerical type, the statement skips over initial blanks (i.e., 
{\tt \spa} and $\eol$), reads the characters of a numerical value, and stops
when the next character could not belong to that value, without passing over
that character. For example, the file goes from
{\tt ABC@$\eol${\spa}123.4{\spa}$\eol$} to
{\tt ABC$\eol${\spa}123.4@{\spa}$\eol$}.
If {\tt X} is of type {\tt CHAR}, the statement treats $\eol$ as if it
were~{\tt\spa}, so programs can distinguish $\eol$ from {\tt\spa} on files
only by explicitly testing for $\eol$. It is an error to execute a {\tt READ}
statement unless the file contains an unread value of the required type.

The statement {\tt READLN(IN)} moves the read mark past the next
$\eol$, changing\break
{\tt ABC@DE$\eol$FG$\eol$} to
{\tt ABCDE$\eol$@FG$\eol$}.
It is an error in an end-of-file condition.

Useful built-in abbreviations are {\tt READ(IN,X$↓1$,...,X$↓n$)}
for

{\obeylines\obeyspaces\let =\ \tt
        BEGIN READ(IN,X$↓1$); $\ldots$ READ(IN,X$↓n$) END
}

%\vfil\eject

\noindent
and {\tt READLN(IN,X$↓1$,...,X$↓n$)} for

{\obeylines\obeyspaces\let =\ \tt
        BEGIN READ(IN,X$↓1$); $\ldots$ READ(IN,X$↓n$) READLN(IN) END
}

The end-of-file
condition {\tt EOF(IN)} is true if the read mark is at the end of
the file. No other input operation is allowed when {\tt EOF} is true,
so if an end-of-file condition is possible, a~program should check
by {\tt EOF} first.

The end-of-line
condition {\tt EOLN(IN)} is true if the read mark is followed by $\eol$,
false if it is followed by any other symbol, and an error at the end
of file. It is the only way to distinguish $\eol$ from {\tt\spa} on an
input file.

If the file involved is {\tt INPUT}, the above operations can be abbreviated
to {\tt READ(X)}, {\tt READLN}, {\tt READ(X$↓1$,...,X$↓n$)},
{\tt READLN(X$↓1$,...,X$↓n$)}, {\tt EOF}, and {\tt EOLN}. That is,
{\tt INPUT} is the default file for reading. It is therefore convenient
to use {\tt INPUT} as the main file from which a program reads.


\bigskip
\line{\bf Non-Text Files \hfil}

If a file is not of type {\tt TEXT}, it can hold values only of one single type.
Say {\tt ANY} is a file of integers.   Then integer values 
can  be
written on it by {\tt WRITE(ANY,I$↓1$,I$↓2$)} 
when  it is open for writing.   When
it is open for reading, values can be read from it to integer variables
 by {\tt READ(ANY,I$↓1$,I$↓2$)}.  
An end-of-file condition can be tested by
{\tt EOF(ANY)}. No other input  or output operations  can be done.   Similar
restrictions apply to files of real, boolean, or character values.   Files
of integer,  real, and  boolean values  may not be in  a form  suitable  for
printing or for reading  on a terminal screen;  they are used  primarily
for communication  between programs,  or between  successive stages  of  a
single program.

\bigskip
\line{\bf Files in General.\hfil}

All files in Pascal except {\tt INPUT} and {\tt OUTPUT} 
must be declared as variables,
of type  either {\tt TEXT} or {\tt FILE OF t}, where {\tt t}~is 
any  type  not  itself
containing files.  [Repetitive.]
(For example, {\tt FILE OF REAL} and 
{\tt FILE OF ARRAY [1..10] OF CHAR}.)  
The names {\tt INPUT} and {\tt OUTPUT} are implicitly declared of type  
{\tt TEXT}, and should not be declared as variables.

Some files are used entirely within a single program; they are written  by
that program, later are  read during the same  execution, and are then  no
longer needed.  Such {\it internal\/} files do not need an external name.  Input
files which  provide data  to the  program  from the  user or  some  other
external source, and output  files for printing  or other subsequent  use,
must have an external name.  Such  {\it external\/} files must be listed in  the
program header  line.   The header  is  of the  form  

{\obeylines\obeyspaces\let =\ \tt
        PROGRAM P(ANY1,ANY2,ANY3); 
}

\noindent
where all internal names of external  files are  listed  (including {\tt INPUT}
and {\tt OUTPUT} if  they are  used).    When the  program  is  executed,  the
user will  be asked for the  external name corresponding  to
each internal name. 

A file may be opened for reading by the command {\tt RESET(ANY)}.  It may be
opened for writing by the command {\tt REWRITE(ANY)}.
 At the  end of  a Pascal  program, all  its files  are
automatically closed.  At  the beginning  of a Pascal  program, the  files
{\tt INPUT} and {\tt OUTPUT} are  automatically and permanently
opened  for  reading  and  writing
respectively.  Other files must be  opened explicitly before any input  or
output operations can be executed.

It is  possible for the  program to  ``see''  the next  single  element on
a file  without actually moving the read  pointer; if the file's  internal 
name is  {\tt IN}, and the file contains  $e↓1 e↓2\ldots e↓{i-1}@e↓i\ldots e↓n$,
 the
expression  {\tt IN$\uparrow$} (or {\tt IN$\wedge$} 
 on  some keyboards) has  the value~$e↓i$; to
discard characters from a text file up to but not including the next space, 
for example,  one could do

{\obeylines\obeyspaces\let =\ \tt
        WHILE IN$\uparrow$<>'{\spa}' DO READ(IN,C).
}

\noindent
The read pointer can be moved one  place to the right without reading,  by
the command {\tt GET(IN)}.  In fact, {\tt READ(IN,C)} 
is an abbreviation  for
{\tt C:=IN$\uparrow$; GET(IN)}. The above example, then, could also be

{\obeylines\obeyspaces\let =\ \tt
        WHILE IN$\uparrow$<>'\spa'DO GET(IN).
}

\noindent
It is, of course, an error to execute {\tt GET(f)} when file~{\tt f} is
exhausted.
[Add section on {\tt PUT}?] 


\vfill\eject

%\bigskip
\line{\bf File Cliches.\hfil}

To read and process every component of a non-text file, or every character of a
text file, with subalgorithms to
initialize before the first and finish after the
last, the standard pattern in Pascal is:

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        RESET(f);(* not needed initially if f is INPUT *)
        initialize;

        WHILE NOT EOF(f) DO
            BEGIN
            READ(f,x);
            process datum in x
            END;

        (* all data processed, at end of file *)

        finish
        END
}
Suppose I have a file containing numerical data, interspersed with spaces.
I~want to process each number, perhaps by adding it to a running total.
When the file is exhausted, I~want to finish up, perhaps by printing the
total. Here are two plausible programs that don't work.

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        initialize;
        WHILE NOT EOF DO
            BEGIN
            READ(X);
            PROCESS X
            END;
        finish
        END
}

\noindent
The program above always fails. After reading the last number, the read mark
is still to the left of at least one character (the final $\eol$), so
{\tt EOF} is still false. Another {\tt READ(X)} is executed, the program
looks for a nonexistent number, and an error stop results. Another
solution, popular because it sometimes works:

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        initialize;
        WHILE NOT EOF DO
            BEGIN
            READLN(X);
            PROCESS X
            END;
        finish
}

\noindent
It fails when there is more than one number on a line, by ignoring all but
the first. It also fails unless the last datum is on the last line.
It would  ail in both ways on the file:

{\obeylines\obeyspaces\let =\ \tt
        {\spa}12.3{\spa}{\spa}45.678{\spa}{$\eol$}{\spa}{\spa}{$\eol$}
}

\noindent
Printing the data files shows the first difficulty, if the reader knows
to look for it, but the second is invisible.

Observe that it is never safe to execute {\tt READLN(X)}, because there
might be more than one number in the current line. It is never safe to
execute {\tt READ(X)} unless {\tt INPUT}$\uparrow$ is non-blank, because
there might be no more numbers. It is almost never safe to do any  input
operation without first checking {\tt EOF}, because the read mark might
be at the end of the file already. We organize the algorithm to do only
what is safe.

On each entry to the iteration, {\tt EOF} is tested. If true, the
iteration is finished; if false, {\tt INPUT}$\uparrow$ may be tested. Inside
the iteration, {\tt INPUT}$\uparrow$ is tested. If it is a space
(or $\eol$ masquerading as a space), it is safe to discard one input
character. If it is not a space, it must be part of a number, and it is
safe to read that number. The solution:

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        initialize;
        WHILE NOT EOF DO
            IF INPUT$\uparrow$='{\spa}') THEN GET(INPUT)
            ELSE
                BEGIN
                READ(X);
                process X
                END;
           finish
           END
}

%\vfill\eject

An alternate method uses a  sentinel in the file  to mark the end  of
the data. A~sentinel is a special value, like 999999, of the same type  as
the data, that can be read by the same {\tt READ} that reads the data.

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        (* RESET(f) if needed *)
        initialize;
        READ(f,X);
        WHILE(X is not a sentinel) DO
            BEGIN
            process X;
            READ(f,X)
            END;
        (* RESET(f) if needed *)
        finish
        END
}

\noindent
The above program is more efficient, needing only one test per  iteration.
Its structure seems rather peculiar; each iteration processes the  number
read on the previous iteration. Only this way can the sentinel be read
without being processed.

%\vfill\eject

To process one line of  characters on a text  file, assuming that
 a~line of data is known to be next on~{\tt f},  so  no preliminary
{\tt EOF} test  is needed:  

{\obeylines\obeyspaces\let =\ \tt
        BEGIN 
        initialize;
        WHILE NOT EOLN(f) DO
            BEGIN
            READ(f,C);
            process C
            END;
        (* next character is end-of-line *)
        READ(f,C); (* or GET(f) or READLN(f) *)
        finish
        END
}

To  process every  line of characters in a text file, with subalgorithms~{\tt  A}
initializing the whole computation, {\tt B}~initializing the  processing
of one line, {\tt D}~finishing the processing of one line, and  
{\tt E}~finishing the whole computation:

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        A;
        (* reset(f) if needed *)
        WHILE NOT EOF(f) DO
            (* process one line *)
            BEGIN
            B;
            WHILE NOT EOLN(f) DO
                BEGIN
                READ(f,C);
                process C
                END;
            READ(f,C);(* discard end-of-line symbol *)
            D
            END;
        (* end of file *)
        E
        END
}

\vfill\eject

{\rmn
{\narrower\smallskip\noindent
{\bf Example:} a program to test that every line of file {\tt f} contains at least
one asterisk:

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        (* RESET(f) if needed *)
        EVERYLINE:=TRUE; (* Until line with no asterisk *)
        WHILE NOT EOF(f) DO
            BEGIN
            THISLINE:=FALSE; (* Until asterisk on current line *)
            WHILE NOT EOLN(f) DO
                BEGIN
                READ(f,C);
                IF C='*' THEN
                    THISLINE:= TRUE
                END;
            READ(f,C);
            IF NOT THISLINE THEN
                EVERYLINE:=FALSE
            END;
        IF EVERYLINE THEN WRITE('EVERY LINE HAS A STAR')
        ELSE WRITE ('NOT EVERY LINE HAS A STAR')
        (* RESET(f) if needed *)
        END
}
\smallskip}
}

\vfill\eject

{\rmn
{\narrower\smallskip\noindent
{\bf Example:} Program to  read a text  file, and left-justify  it with as  many
words as possible on a line. The original line breaks are ignored.

[RWF: Debug this and comment on it]

{\obeylines\obeyspaces\let =\ \tt
        BEGIN PROGRAM(---);
        Declarations;
        PROCEDURE PROCESS (X: CHAR);
        BEGIN
        IF X <> '{\spa}' THEN
            BEGIN
            LETCOUNT:= LETCOUNT+1; (* WORD LENGTH *)
            WORD [LETCOUNT]:=X
            END
        ELSE
            BEGIN
            IF LINELENGTH+LETCOUNT+1>LIMIT THEN
                BEGIN	
               	WRITELN;
                LINELENGTH:=0
                END;
            IF LINELENGTH>0 THEN
                BEGIN
                WRITE (' ');
                LINELENGTH:=LINELENGTH+1+LETCOUNT
                END
            ELSE LINELENGTH:=LETCOUNT;
            FOR I:=1 TO LETCOUNT DO
                WRITE(WORD [I])
            LETCOUNT:=0
            END
        END;	

        BEGIN (* MAIN PROGRAM *)

        LETCOUNT:=0;
        LINELENGTH:=0;
        LASTC:= '{\spa}';

        WHILE NOT EOF DO
            BEGIN
            READ(C);
            IF (LASTC <> '{\spa}' ) OR (C<> '{\spa}' ) THEN
                PROCESS(C);
            LASTC:=C
            END;
        (* RESET if needed *)
        END
}

If running time is important, the call on {\tt PROCESS(C)} can  be
replaced by a slightly  modified copy of the  procedure body. The  program
uses the fact that {\tt READ} treats the end-of-line symbol as a space.
\smallskip}

}

\bigskip
\line{\bf Interactive Computing [Explain buffer]\hfil}

Pascal was designed before 1974 for use on computers that took input from
already completed files, and wrote results on files that were not seen by
people until they were complete. Many current computers, however, accomodate
programs that ``converse'' with their users. The computer may display
information on a viewing screen, ask questions, and accept answers as they
are typed by a human user. Examples of such programs are word processing
programs, video games, personal filing systems, and computer aided
instruction.

Most Pascal implementations on interactive computers use non-standard
and non-uniform features to communicate with the user interactively.
In this text, we will use these operations:

\smallskip
\display 25pt:$\bullet$:
{\tt WRITESCREEN(X)} displays the value of~{\tt X} on the viewing screen.

\smallskip
\display 25pt:$\bullet$:
{\tt WRITELNSCREEN} terminates a line on the viewing screen.

\smallskip
\display 25pt:$\bullet$:
{\tt READKEYS(X)} accepts a value of~{\tt X} from the user's keyboard.

\smallskip
\display 25pt:$\bullet$:
{\tt EOLNKEYS} is true if the next input symbol from the user's keyboard
is the end-of-line (carriage return) symbol.

\smallskip
\display 25pt:$\bullet$:
{\tt EOFKEYS} is true if the next input symbol from the user's keyboard
is an end-of-file symbol.

\smallskip
[Need {\tt READLNKEYS}]

\smallskip
Appendix \_\_\_ shows how the above operations are done in several widely
used Pascal implementations. In a~course, the instructor should provide
replacements for each of the above operations.

\bigskip
\line{{\bf Pseudo-files.} [Non-standard, Stanford only] [Incorrect about modes]\hfil}

Pascal treats several entities  more or less as  if they were files.   The
external name {\tt TTY:} (note the colon) can be used to let the  corresponding
internal name represent data typed at  the terminal keyboard when in  read
mode, and represent  the terminal  screen when  in write  mode.  In  write
mode, this is sometimes useful to see the results of a program immediately
as it writes them, especially if the lines of output are no more than  the
80-character width of the screen.  In read mode, the use of external  name
{\tt TTY:} can not  be recommended; a  program designed for  input from a  true
file is usually not well designed for keyboard input.  See \_\_\_
for details.

The internal name {\tt TTY} can also be used to represent the terminal  keyboard
and screen.  Output commands to {\tt TTY}, such as 
{\tt WRITE(TTY,X1,X2)}, are  quite
analogous to output commands for files.   Input commands, however, differ.

During the execution of a Pascal program, the sequence of characters typed
at the keyboard is used as if it were a text file called {\tt TTY} for all input
operations.  A line typed in is made available to the program only when it
is completed with a carriage return; up until entry of the carriage return
the user may modify  the line at will,  for example by backspacing.   When
the program has consumed all available keyboard input, it stops and  waits
until the user  has typed  another complete  line.  To  avoid impasses,  a
program should request  more input  before consuming  all available  input
characters (in particular,  the final carriage  return).  The  pseudo-file
with internal name {\tt TTY} is automatically
initialized to  an empty line,  as if a  single
carriage return  had  already been  typed  in,  so that  the  program  can
continue execution  (Older versions  of the  translator required  
at least an $\eol$ from the
keyboard
before  the  program  would  start).  The  pseudo-file {\tt TTY} is  not
mentioned in the program header, nor is it declared.  It is treated as  of
type {\tt TEXT}.  For input pseudo-files {\tt TTY} or {\tt TTY:}, 
an end-of-file  condition is
created  only  by  typing {\tt CONTROL/Z};  usually  programs  intended  for
terminal input do not use the end-of-file condition.

The external name {\tt LPT:} ( note  the colon) can be  used as a pseudo-file, in
write mode, for information which is to be printed automatically upon completion
of execution, and is not to be retained as a permanent file.

\bigskip

\noindent
{\bf Terminal Input Cliches.} [RWF: relocate] [Give Stanford equivalents] [Show
numbers too]

Reading data as lines of characters from the terminal is typically done by
the subprogram below.

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        INITIALIZE;
        WRITESCREEN(prompting message); 
        (* Explain to the user what he must type *)
        READLNKEYS; 
        (* discard remnants of previous line; program waits here
            until user completes a new line *)
        WHILE NOT EOLNKEYS DO
            BEGIN
            READKEYS(C);
            Process C
            END;
        Process carriage return, if required, without reading it.
        END
}

Alternatively, [non-standard]
a line  can be  read into a string variable~{\tt S}, 
of  type {\tt PACKED} 
{\tt ARRAY[1..80] OF CHAR}; the subprogram below  tests each line for validity  and
reads again until an acceptable line has been read.

\vfill\eject

{\obeylines\obeyspaces\let =\ \tt
        BEGIN
        WRITESCREEN(prompting message);
        BADDATA:=TRUE;
        WHILE BADDATA DO
            BEGIN
            READLNKEYS; 
            (* Discard remnants of earlier line *)
            READKEYS(S); 
            (* Puts in S the entire line except carriage return *)
            IF(S is acceptable) THEN
                BADDATA:=FALSE
            ELSE
                WRITESCREEN(reprompting message)
                (* Explain exact requirements for correct input *)
            END
        END
}

\bigskip
\line{{\bf The Naming of Files.} [Non-standard]\hfil}

Like the naming of cats [1], the naming of files should not be  undertaken
lightly.  See the section of the LOTS Overview on file descriptors [ ] for
the rules  about directory  names.  The  extension field  of your  program
should normally be {\tt PGO}, for translation by the {\tt PASSGO}
translator.  If your
program uses a separate library of subprograms, use the {\tt PASCAL} translator
by making {\tt PAS} the extension field.   The file name proper of your  program
for a  course  assignment  should  begin with  an  identification  of  the
assignment number.   A~program  for assignment~8, to  do an  integration,
might be in file {\tt P8INT.PGO}.  The data  file for a program should have  the
same name except  for extension  field {\tt DAT} (e.g., {\tt P8INT.DAT}); 
the  output
file should  have the  same name  except for  extension field {\tt OUT} (e.g.,
{\tt P8INT.OUT}).  An interactive program should keep a permanent record of  all
input, perhaps  on a  file with  extension field {\tt LOG}; this  allows  later
confirmation that data were entered correctly.

It is a common  disastrous error to  give the name of  the program as  the
external name of the output file; this results in deletion of the  program
file.  When this happens,  (1)  DO NOT LOGOUT,  (2) DO NOT EXPUNGE,  until
the deleted file has been recovered.   See Overview  for
methods to locate and restore deleted files.  As a safety measure, you can
set the normal number of file generations retained in your directory to~2.
(E.g.,  if your program is in file  {\tt P8INT.PGO.10},  and you send output to 
{\tt P8INT.PGO}, it will  go to  {\tt P8INT.PGO.11},  
and generations~10 and~11 will 
both be retained.)  If you  do so, you  should  delete all  obsolete files  
at  the end  of  each terminal session.  

\bigskip
\line{{\bf Test Files.} [Move to section on testing.]\hfil}

In testing a program which will use a large data file, such as a dictionary
for a spelling checker program, use a much smaller test file, for several
reasons:

\disleft 25pt:(1):
Your testing will take less time.

\disleft 25pt:(2):
You will be able to predict exactly what the program should do.

\disleft 25pt:(3):
You can easily change the file to exercise all parts of the program. 
(Long words, words which come after the last dictionary entry, ... .)



\bigskip
\line{\copyright 1983 Robert W. Floyd.\hfil}
%First draft (not published) ??\hfil}
%revised: Date; subsequently revised.\hfill}

\bye